package object

import "errors"

// Result represents a result which can either be a success (Ok) or an error (Err)
type Result[T any] struct {
	Value T
	Err   error
}

// Ok creates a Result with a value (success case)
func Ok[T any](value T) Result[T] {
	return Result[T]{Value: value}
}

// Err creates a Result with an error (error case)
func Err[T any](err error) Result[T] {
	return Result[T]{Err: err}
}

// IsOk checks if the result is Ok (successful)
func (r Result[T]) IsOk() bool {
	return r.Err == nil
}

// IsErr checks if the result is Err (error)
func (r Result[T]) IsErr() bool {
	return r.Err != nil
}

// Unwrap extracts the value from the Result, panicking if it's an error
func (r Result[T]) Unwrap() T {
	if r.Err != nil {
		panic(r.Err)
	}
	return r.Value
}

// UnwrapErr extracts the error from the Result, panicking if it's an Ok
func (r Result[T]) UnwrapErr() error {
	if r.Err == nil {
		panic("called UnwrapErr on a Result that was Ok")
	}
	return r.Err
}

// Example function that uses Result
func divide(a, b int) Result[int] {
	if b == 0 {
		return Err[int](errors.New("division by zero"))
	}
	return Ok(a / b)
}
